/*
 * 
 * 
 * 
 */
package com.hboxs.asl.service.impl;

import com.hboxs.asl.Filter;
import com.hboxs.asl.Page;
import com.hboxs.asl.Pageable;
import com.hboxs.asl.dao.CouponCodeDao;
import com.hboxs.asl.dao.MemberDao;
import com.hboxs.asl.entity.Coupon;
import com.hboxs.asl.entity.CouponCode;
import com.hboxs.asl.entity.Member;
import com.hboxs.asl.service.CouponCodeService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.persistence.LockModeType;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Service - 优惠码
 */
@Service("couponCodeServiceImpl")
public class CouponCodeServiceImpl extends BaseServiceImpl<CouponCode, Long> implements CouponCodeService {

    @Resource(name = "couponCodeDaoImpl")
    private CouponCodeDao couponCodeDao;
    @Resource(name = "memberDaoImpl")
    private MemberDao memberDao;

    @Resource(name = "couponCodeDaoImpl")
    public void setBaseDao(CouponCodeDao couponCodeDao) {
        super.setBaseDao(couponCodeDao);
    }

    @Transactional(readOnly = true)
    public boolean codeExists(String code) {
        return couponCodeDao.codeExists(code);
    }

    @Transactional(readOnly = true)
    public CouponCode findByCode(String code) {
        return couponCodeDao.findByCode(code);
    }

    public CouponCode build(Coupon coupon, Member member) {
        return couponCodeDao.build(coupon, member);
    }

    public List<CouponCode> build(Coupon coupon, Member member, Integer count) {
        return couponCodeDao.build(coupon, member, count);
    }

    public CouponCode exchange(Coupon coupon, Member member) {
        Assert.notNull(coupon);
        Assert.notNull(member);

        memberDao.lock(member, LockModeType.PESSIMISTIC_WRITE);
        member.setPoint(member.getPoint().subtract(coupon.getPoint()));
        memberDao.merge(member);

        return couponCodeDao.build(coupon, member);
    }

    @Transactional(readOnly = true)
    public Page<CouponCode> findPage(Member member, Pageable pageable) {
        return couponCodeDao.findPage(member, pageable);
    }

    @Transactional(readOnly = true)
    public Long count(Coupon coupon, Member member, Boolean hasBegun, Boolean hasExpired, Boolean isUsed) {
        return couponCodeDao.count(coupon, member, hasBegun, hasExpired, isUsed);
    }

    @Override
    public List<CouponCode> findListByPrice(Member member, Boolean hasBegun, Boolean hasExpired, Boolean isUsed, BigDecimal couponPrice) {
        List<Filter> fs = new ArrayList<>();
        List<com.hboxs.asl.Order> os = new ArrayList<>();
        fs.add(Filter.le("coupon.maximumPrice", couponPrice));
        os.add(com.hboxs.asl.Order.desc("coupon.cut"));
        return couponCodeDao.findList(member, hasBegun, hasExpired, isUsed, fs, os);
    }

    @Override
    public Long countUnusedCouponCodes(Member member) {
        return couponCodeDao.countUnusedCouponCodes(member);
    }

    @Override
    public Long countUsedCouponCodes(Member member) {
        return couponCodeDao.countUsedCouponCodes(member);
    }

    @Override
    public Long countOverdueCouponCodes(Member member) {
        return couponCodeDao.countOverdueCouponCodes(member);
    }

    @Override
    public List<CouponCode> findUnusedCouponCodes(Member member) {
        return couponCodeDao.findUnusedCouponCodes(member);
    }

    @Override
    public List<CouponCode> findUsedCouponCodes(Member member) {
        return couponCodeDao.findUsedCouponCodes(member);
    }

    @Override
    public List<CouponCode> findOverdueCouponCodes(Member member) {
        return couponCodeDao.findOverdueCouponCodes(member);
    }


}